home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / doom / addons.zip / JOY2KEY.ZIP / JOY2KEY.ASM < prev    next >
Assembly Source File  |  1997-04-12  |  20KB  |  592 lines

  1. ;***********************************************************************
  2. ; Source       : joy2key.asm
  3. ; Copyright    : Michael Rans
  4. ; Purpose      : Terminate and Stay Resident Program to convert joystick
  5. ;                movements to simulated keyboard key presses
  6. ;***********************************************************************
  7.  
  8. key1    MACRO   NUMBER                  ; Write keyboard command to port 64h
  9.         LOCAL   ll1, cc1
  10.         mov     cx,07d0h
  11. ll1:    in      al,64h
  12.         test    al,02h
  13.         je      cc1
  14.         loop    ll1
  15. cc1:
  16.         mov     al, NUMBER
  17.         out     64h, al
  18.         ENDM
  19.  
  20. key2    MACRO   NUMBER                  ; Write keyboard data to port 60h
  21.         LOCAL   ll2, cc2
  22.         mov     cx,07d0h
  23. ll2:    in      al,64h
  24.         test    al,02h
  25.         je      cc2
  26.         loop    ll2
  27. cc2:
  28.         mov     al, NUMBER
  29.         out     60h, al
  30.         ENDM
  31.  
  32. CODESG    SEGMENT    PARA
  33.         ASSUME  CS:CODESG
  34.     org    100h
  35. begin:
  36.     jmp    initialise    ; jump to initialise section
  37.  
  38. ;       Data for TSR
  39. int1c   dd      ?               ; contains timer (1ch) interrupt address
  40. int70   dd      ?               ; contains timer (70h) interrupt address
  41. mh      db      00h             ; horizontally centred
  42. mv      db      00h             ; vertically centred (1=centred)
  43. keyr    db      048h+128        ; scan code for "up released"
  44. flag    db      00h             ; scan codes for each of the arrow keys
  45.                                 ; (released) in succession are pushed to the
  46.                                 ; keyboard. This is a counter to see if all 4
  47.                                 ; directions have been pushed.
  48. pos     db      00h             ; look at horizontal or vertical position
  49. key     db      00h             ; current key moved into here
  50. prevkey db      00h             ; previous key (moved from key into here)
  51. up      dw      ?               ; up position (1/4 way movement of joystick)
  52. down    dw      ?               ; down position  ( " )
  53. left    dw      ?               ; left position  ( " )
  54. right   dw      ?               ; right position ( " )
  55.  
  56. ;***********************************************************************
  57. ; Procedure    : slow (18.5Hz) timer
  58. ; Purpose      : timer interrupt handler (Interrupt 1ch)
  59. ; Entry           : [nothing required]
  60. ; Exit           : [nothing altered]
  61. ;***********************************************************************
  62.  
  63. timer1c:
  64.     push    ax
  65.         push    bx
  66.         push    cx
  67.         push    dx
  68.         push    ds
  69.         push    di
  70.         push    si
  71.  
  72.         mov     ax, 8600h               ; Call wait function
  73.         xor     cx, cx                  ; This starts 70h interrupt
  74.         mov     dx, 7a2h                ; Wait for 7a2h microseconds
  75.         int     15h
  76.  
  77.         pop     si
  78.         pop     di
  79.     pop    ds
  80.         pop     dx
  81.         pop     cx
  82.         pop     bx
  83.     pop    ax
  84.         jmp     cs:int1c                ; jump to timer (1ch) interrupt
  85.                                         ; routine
  86.  
  87. ;***********************************************************************
  88. ; Procedure    : fast (1024Hz) timer
  89. ; Purpose      : timer interrupt handler (Interrupt 70h)
  90. ; Entry           : [nothing required]
  91. ; Exit           : [nothing altered]
  92. ;***********************************************************************
  93.  
  94. timer:
  95.     push    ax
  96.         push    bx
  97.         push    cx
  98.         push    dx
  99.         push    ds
  100.         push    di
  101.         push    si
  102.  
  103.         xor     bx,bx
  104.         mov     dx, 0201h
  105.         cli
  106.         test    pos, 00000001b          ; Alternate between checking
  107.                                         ; horizontal and vertical position
  108.                                         ; to allow for diagonal movement
  109.         je      vertical
  110. horizontal:                             ; check horizontal position
  111.         inc     pos
  112.         out     dx, al
  113. joysticklooph:
  114.         inc     bx           
  115.         in      al, dx
  116.         cmp     bx, 0ffffh
  117.         jne     conth
  118.         jmp     exit
  119. conth:
  120.         test    al, 00000001b
  121.         jne     joysticklooph
  122.         jmp     testkey
  123. vertical:                               ; check vertical position
  124.         dec     pos
  125.         out     dx, al
  126. joystickloopv:
  127.         inc     bx           
  128.         in      al, dx
  129.         cmp     bx, 0ffffh
  130.         jne     contv                   ; "contv" below "dokey" placed here
  131.                                         ; to reduce branch distance
  132.         jmp     exit
  133. dokey:
  134.         cmp     key, bl                 ; Compare current key and key
  135.         jne     movk
  136.         jmp     pushkey
  137. movk:
  138.         mov     al, key
  139.         mov     prevkey, al             ; key -> previous key
  140.         mov     key, bl                 ; Current key -> key
  141.         jmp     pushkey
  142. contv:
  143.         test    al, 00000010b
  144.         jne     joystickloopv
  145.  
  146.         cmp     bx, up                  ; Is stick 1/4 way up?
  147.         jg      notup
  148.         mov     bl, 048h                ; Up arrow = 48h
  149.         mov     mv, 00h                 ; Reset flags
  150.         mov     flag, 00h
  151.         cmp     prevkey, bl             ; Compare key before last to current
  152.         je      dokey
  153.  
  154. ; Since we are checking alternately the horizontal and vertical position of
  155. ; the joystick, prevkey will contain the same key as we are going to push
  156. ; to the keyboard even if we are going diagonally. eg. rrrrrr where r=right
  157. ; urururur where u=up, r=right - every other key is the same for a diagonal
  158. ; If prevkey doesn't equal the key we are about to push, instead we send
  159. ; "release prevkey" ie. previous key released. We pretend we have sent the
  160. ; key we were going to send (in this case 048h or up). This is because the
  161. ; program when it is checking the alternate axis, if it finds the stick is
  162. ; centred on this axis, it sends the other axis's key if appropriate. Phew!
  163. ; Sorry if this makes no more sense than looking at the code.
  164.         mov     bl, prevkey
  165.         mov     al, key
  166.         mov     prevkey, al
  167.         mov     key, 048h
  168.         add     bl, 128                 ; Turn key "press" to "release" code
  169.         jmp     pushkey
  170. notup:
  171.         cmp     bx, down                ; Is stick 1/4 way down?
  172.         jl      nokeyv
  173.         mov     bl, 050h                ; Down arrow = 50h
  174.         mov     mv, 00h                 ; Reset flags
  175.         mov     flag, 00h
  176.         je      dokey
  177.         cmp     prevkey, bl             ; Compare key before last to current
  178.         je      dokey
  179.         mov     bl, prevkey
  180.         mov     al, key
  181.         mov     prevkey, al
  182.         mov     key, 050h
  183.         add     bl, 128                 ; Turn key "press" to "release" code
  184.         jmp     pushkey
  185. nokeyv:                                 ; Vertically centred
  186.         mov     mv, 01h                 ; Set vertically centred flag
  187.         cmp     mh, 01h                 ; check if horizontally centred
  188.         jne     nocenth
  189.         cmp     flag, 09h               ; If flag=5, don't send any more keys
  190.                                         ; to the keyboard (until the joystick
  191.                                         ; is moved again)
  192.         jne     centrh
  193.         jmp     exit
  194. centrh:
  195.         inc     flag
  196.         cmp     flag, 01h               ; If flag=1, a "release key" is still
  197.                                         ; to be sent to the keyboard
  198.         je      nocenth
  199.         jmp     keyrelease
  200. nocenth:
  201.         mov     bl, key
  202.         mov     cl, prevkey
  203.         cmp     cl, bl                  ; If key and previous key are same,
  204.                                         ; no need to move key to prevkey
  205.         jne     difkey 
  206.         jmp     pushkey
  207. dokey2:
  208.         cmp     key, bl                 ; Compare current key and key
  209.         jne     movk2
  210.         jmp     pushkey
  211. movk2:
  212.         mov     al, key
  213.         mov     prevkey, al             ; key -> previous key
  214.         mov     key, bl                 ; Current key -> key
  215.         jmp     pushkey
  216. difkey:
  217.         mov     prevkey, bl             ; Swap previous key and key
  218.         mov     key, cl
  219.         mov     bl, cl
  220.         add     bl, 128                 ; Turn key "press" to "release" code
  221.         jmp     pushkey
  222. testkey:
  223.         cmp     bx, left                ; Is stick 1/4 way left?
  224.         jg      notleft
  225.         mov     bl, 04bh                ; Left arrow = 4bh
  226.         mov     mh, 00h                 ; Reset flags
  227.         mov     flag, 00h
  228.         cmp     prevkey, bl             ; Compare key before last to current
  229.         je      dokey2
  230.         mov     bl, prevkey
  231.         mov     al, key
  232.         mov     prevkey, al
  233.         mov     key, 04bh
  234.         add     bl, 128                 ; Turn key "press" to "release" code
  235.         jmp     pushkey
  236. notleft:
  237.         cmp     bx, right               ; Is stick 1/4 way right?
  238.         jl      nokeyh
  239.         mov     bl, 04dh                ; Right arrow = 4dh
  240.         mov     mh, 00h                 ; Reset flags
  241.         mov     flag, 00h
  242.         cmp     prevkey, bl             ; Compare key before last to current
  243.         je      dokey2
  244.         mov     bl, prevkey
  245.         mov     al, key
  246.         mov     prevkey, al
  247.         mov     key, 04dh
  248.         add     bl, 128                 ; Turn key "press" to "release" code
  249.         jmp     pushkey
  250. nokeyh:                                 ; Horizontally centred
  251.         mov     mh, 01h                 ; Set horizontally centred flag
  252.         cmp     mv, 01h                 ; check if vertically centred
  253.         jne     nocentv
  254.         cmp     flag, 09h               ; If flag=5, don't send any more keys
  255.                                         ; to the keyboard (until the joystick
  256.                                         ; is moved again)
  257.         jne     centrv
  258.         jmp     exit
  259. centrv:
  260.         inc     flag
  261.         cmp     flag, 01h               ; If flag=1, a "release key" is still
  262.                                         ; to be sent to the keyboard
  263.         je      nocentv
  264.         jmp     keyrelease
  265. nocentv:
  266.         mov     bl, key
  267.         mov     cl, prevkey
  268.         cmp     cl, bl                  ; If key and previous key are same,
  269.                                         ; no need to move key to prevkey
  270.         je      pushkey
  271.         jmp     difkey
  272. pushkey:                                ; Program keyboard with scan
  273.                                         ; code in bl
  274.         key1    0ADH                    ; Disable keyboard
  275.         key1    061H                    ; Program keyboard
  276.         key2    bl                      ; with scan code in bl
  277.         key1    021H                    ; Load keyboard command
  278.         key1    0AEH                    ; Enable keyboard
  279. exit:
  280.         sti
  281.         pop     si
  282.         pop     di
  283.     pop    ds
  284.         pop     dx
  285.         pop     cx
  286.         pop     bx
  287.     pop    ax
  288.         jmp     cs:int70                ; jump to timer (70h) interrupt
  289.                                         ; routine
  290. keyrelease:
  291.         mov     bl, keyr
  292.         add     keyr, 03h               ; Cycle through arrow keys (released)
  293.         cmp     keyr, 04eh+128
  294.         je      deck
  295.         cmp     keyr, 053h+128
  296.         jne     pushkey
  297.         mov     keyr, 048h+128
  298.         jmp     pushkey
  299. deck:
  300.         dec     keyr                    ; Correct for 0cdh instead of 0ceh
  301.         jmp     pushkey
  302. endtimer:
  303. ;       End of TSR
  304.  
  305. ;       Data for initialisation program
  306. mesg0   db      'Centre the joystick, then press button 2$'
  307. mesg1   db      'Move joystick to top left, then press button 1$'
  308. mesg2   db      'Move joystick to bottom right, then press button 1$'
  309. errmsg  db      'No joystick connected',10,10,'$'
  310. centh   dw      ?
  311. centv   dw      ?
  312. lefth   dw      ?
  313. upv     dw      ?
  314. righth  dw      ?
  315. downv   dw      ?
  316. string  db      17 DUP('$')
  317.  
  318. ;       Subroutines for initialisation program
  319. disp:
  320.         lea     di, string
  321.         mov     cx,16           ; number of bits in byte -> cx (counter)
  322. loop1:  rol     bx,1            ; rotate bits left 1 place
  323.     jc      print1        ; if 1 enters carry flag go to print1
  324.         mov     al,48           ; '0' = character to be printed
  325.     jmp     print
  326. print1: mov     al,49           ; '1' = character to be printed
  327. print:
  328.         mov     [di], al
  329.         inc     di
  330.         loop    loop1
  331.         ret
  332.  
  333. button1:                                ;  Wait till button 1 pressed
  334.         mov     dx, 0201h
  335. waitbut1:
  336.         in      al, dx
  337.         test    al, 00010000b
  338.         jne     waitbut1
  339.         ret
  340.  
  341. button2:                                ;  Wait till button 2 pressed
  342.         mov     dx, 0201h
  343. waitbut2:
  344.         in      al, dx
  345.         test    al, 00100000b
  346.         jne     waitbut2
  347.         ret
  348.  
  349. horiz:                                  ;  Measure horizontal position
  350.         xor     bx,bx
  351.         mov     dx, 0201h
  352.         cli
  353.         out     dx, al
  354. jlooph:
  355.         inc     bx           
  356.         in      al, dx
  357.         cmp     bx, 0ffffh
  358.         jne     conh
  359.         mov     ah,02h
  360.         mov     bx,00h
  361.         mov     dx,0b1fh
  362.         int     10h
  363.         mov     ah,09h
  364.         lea     dx, errmsg
  365.         int     21h
  366.         mov     ax, 4c00h
  367.         int     21h
  368. conh:
  369.         test    al, 00000001b
  370.         jne     jlooph
  371.         sti
  372.         ret
  373. vert:                                   ;  Measure vertical position
  374.         xor     bx,bx
  375.         mov     dx, 0201h
  376.         cli
  377.         out     dx, al
  378. jloopv:
  379.         inc     bx           
  380.         in      al, dx
  381.         cmp     bx, 0ffffh
  382.         jne     conv
  383.         mov     ah,02h
  384.         mov     bx,00h
  385.         mov     dx,0b1fh
  386.         int     10h
  387.         mov     ah,09h
  388.         lea     dx, errmsg
  389.         int     21h
  390.         mov     ax, 4c00h
  391.         int     21h
  392. conv:
  393.         test    al, 00000010b
  394.         jne     jloopv
  395.         sti
  396.         ret
  397.  
  398. initialise:
  399.         mov     ax,0600h
  400.         mov     bh,07h
  401.         mov     cx,0000h
  402.         mov     dx,184fh
  403.         int     10h
  404.  
  405.         call    horiz
  406.         mov     ah,02h
  407.         mov     bx,00h
  408.         mov     dx,0410h
  409.         int     10h
  410.         mov     ah,09h
  411.         lea     dx, mesg1
  412.         int     21h
  413.  
  414.         call    button1
  415.         call    horiz
  416.         mov     lefth, bx               ;   leftmost position
  417.         call    disp
  418.         mov     ah,02h
  419.         mov     bx,00h
  420.         mov     dx,0d10h
  421.         int     10h
  422.         mov     ah,09h
  423.         lea     dx, string
  424.         int     21h
  425.         call    vert
  426.         mov     upv, bx                 ;   uppermost position
  427.         call    disp
  428.         mov     ah,02h
  429.         mov     bx,00h
  430.         mov     dx,0a22h
  431.         int     10h
  432.         mov     ah,09h
  433.         lea     dx, string
  434.         int     21h
  435.  
  436.         mov     ah,02h
  437.         mov     bx,00h
  438.         mov     dx,0610h
  439.         int     10h
  440.         mov     ah,09h
  441.         lea     dx, mesg0
  442.         int     21h
  443.  
  444.         call    button2
  445.         call    horiz
  446.         mov     centh, bx               ;   middle position (horizontally)
  447.         call    disp
  448.         mov     ah,02h
  449.         mov     bx,00h
  450.         mov     dx,0c22h
  451.         int     10h
  452.         mov     ah,09h
  453.         lea     dx, string
  454.         int     21h
  455.         call    vert
  456.         mov     centv, bx               ;   middle position (vertically)
  457.         call    disp
  458.         mov     ah,02h
  459.         mov     bx,00h
  460.         mov     dx,0e22h
  461.         int     10h
  462.         mov     ah,09h
  463.         lea     dx, string
  464.         int     21h
  465.  
  466.         mov     ah,02h
  467.         mov     bx,00h
  468.         mov     dx,0810h
  469.         int     10h
  470.         mov     ah,09h
  471.         lea     dx, mesg2
  472.         int     21h
  473.  
  474.         call    button1
  475.         call    horiz
  476.         mov     righth, bx              ;   rightmost position
  477.         call    disp
  478.         mov     ah,02h
  479.         mov     bx,00h
  480.         mov     dx,0d35h
  481.         int     10h
  482.         mov     ah,09h
  483.         lea     dx, string
  484.         int     21h
  485.         call    vert
  486.         mov     downv, bx               ;   lowermost position
  487.         call    disp
  488.         mov     ah,02h
  489.         mov     bx,00h
  490.         mov     dx,1022h
  491.         int     10h
  492.         mov     ah,09h
  493.         lea     dx, string
  494.         int     21h
  495.  
  496. ;       If the joystick is moved beyond 1/4 way between the centre and
  497. ;       the furthest position in a direction, the key will be simulated.
  498. ;       This bit calculates this 1/4 way position from the info. collected
  499. ;       above. It simply works out 1/4 way between the centre value and
  500. ;       the value when the joystick is pushed as far as possible in a
  501. ;       direction. The calculated 1/4 way points are stored in memory
  502. ;       locations up, down, left and right for the TSR above to use.
  503.         mov     ax, upv
  504.         mov     bx, centv
  505.         mov     cx, bx
  506.         sub     cx, ax
  507.         sar     cx, 02
  508.         sub     bx, cx
  509.         mov     up, bx
  510.         call    disp
  511.         mov     ah,02h
  512.         mov     bx,00h
  513.         mov     dx,1322h
  514.         int     10h
  515.         mov     ah,09h
  516.         lea     dx, string
  517.         int     21h
  518.  
  519.         mov     ax, downv
  520.         mov     bx, centv
  521.         sub     ax, bx
  522.         sar     ax, 02
  523.         add     bx, ax
  524.         mov     down, bx
  525.         call    disp
  526.         mov     ah,02h
  527.         mov     bx,00h
  528.         mov     dx,1722h
  529.         int     10h
  530.         mov     ah,09h
  531.         lea     dx, string
  532.         int     21h
  533.  
  534.         mov     ax, lefth
  535.         mov     bx, centh
  536.         mov     cx, bx
  537.         sub     cx, ax
  538.         sar     cx, 02
  539.         sub     bx, cx
  540.         mov     left, bx
  541.         call    disp
  542.         mov     ah,02h
  543.         mov     bx,00h
  544.         mov     dx,1510h
  545.         int     10h
  546.         mov     ah,09h
  547.         lea     dx, string
  548.         int     21h
  549.  
  550.         mov     ax, righth
  551.         mov     bx, centh
  552.         sub     ax, bx
  553.         sar     ax, 02
  554.         add     bx, ax
  555.         mov     right, bx
  556.         call    disp
  557.         mov     ah,02h
  558.         mov     bx,00h
  559.         mov     dx,1535h
  560.         int     10h
  561.         mov     ah,09h
  562.         lea     dx, string
  563.         int     21h
  564.  
  565.         cli                             ; disable maskable external interrupts
  566.         mov     ah,35h                  ; get interrupt table address
  567.         mov     al,70h                  ; for timer interrupt (70h)
  568.     int    21h
  569.         mov     word ptr int70,bx       ; save it
  570.         mov     word ptr int70+2,es
  571.         mov     ah,25h                  ; set interrupt table address
  572.         mov     al,70h                  ; for timer interrupt
  573.         mov     dx,offset timer         ; to my timer routine's address
  574.     int    21h
  575.         mov     ah,35h                  ; get interrupt table address
  576.         mov     al,1ch                  ; for timer interrupt (1ch)
  577.     int    21h
  578.         mov     word ptr int1c,bx       ; save it
  579.         mov     word ptr int1c+2,es
  580.         mov     ah,25h                  ; set interrupt table address
  581.         mov     al,1ch                  ; for timer interrupt
  582.         mov     dx,offset timer1c       ; to my timer routine's address
  583.     int    21h
  584.     mov    ah,31h
  585.         mov     dx,offset endtimer      ; length of program
  586.         sar     dx, 4                   ; Since paragraphs not bytes!
  587.         inc     dx
  588.         sti                             ; enable maskable external interrupts
  589.         int     21h                     ; make program a TSR
  590. CODESG    ENDS
  591.     END    begin
  592.